//
//  main.m
//  NSString
//
//  Created by admin on 2019/8/1.
//  Copyright © 2019 猫爷爷的酱醋茶. All rights reserved.
//

/*
 
 NSString 本质是一个类，创建的对象用来存储字符串
 
    NSString *str = @"jcak";  @"jack" 本质是一个NSString对象，str的值是这个对象的地址。
    这个字符串对象是存储在常量区（数据段）的
 
    NSString *str2 = [NSString stringWithFormar:@"jack"];
    NSStirng *str2 = [NSString new];
    创建的对象是存储在堆中的。
 
     NSLog(@"str = %p",str); //输出结果为地址，因为 %p 打印的是指针变量的值
     NSLog(@"str = %@",str); //输出结果为”jack“，因为 %@ 打印的是指针变量指向的对象

字符串的恒定性
    a）当在内存中创建一个字符串对象之后，这个字符串对象的内容就无法更改
    当我们重新为字符串初始化的时候，并不是修改原来的字符串对象，而是重新的创建一个字符串对象，将这个字符串对象的地址重新复制给字符串指针变量。
    b）当系统准备要在内存中创建字符串的时候，会先检查相应的内存区中是否存在相同的字符串
    如果有，直接指向，如果没有才会重新创建。
 
    例：NSStringAddress();
 
NSString 常用的类方法
    1.  + (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;
        将C语言字符串转换成OC字符串 - 应用场景 scanf()、gets()、fgets()接收的都是C语言字符串
      例：Conversion();

    2.  + (instancetype)stringWithFormat:(NSString *)format, ...;
        拼接字符串
      例：Splice();
 
NSString 常用的对象方法
 
1. length 计算字符串长度 返回值为NSUInter 其实就是unsigned long
    [str length];
 
 
2. 通过字符串下标取出对应的值  提取中文输出需要用%C  中文在OC中占据两个字节
    [str characterAtIndex:];

 
3. 判断字符串时候相等 - 判断两个字符串的内容时候相等，不能用==去判断，因为==比较的是两个指针变量的地址是否相同
    [str1 isEqualToString:str2]; 例：ObjectMethod();
 
 
4. 判断两个字符串的大小
 
    a）int res = [name compare:name0]; //默认是完全匹配的对比
        - (NSComparisonResult)compare:(NSString *)string;
        返回值类型NSComparisonResult 是一个枚举类型，完全可以用int接，里面的值为-1，0，1
 
    b）如果需要忽略大小写：
        [str1 compare:str2 options:NSCaseInsensitiveSearch];
 
    c）比较字符串中数字的大小
        [str1 compare:str2 options:NSNumericSearch];
 
 
5.OC字符串和C语言字符串的互转 - 例：Conversion();
 
     //C语言转化为OC语言
     NSString *userName = [NSString stringWithUTF8String:name];
     NSLog(@"用户昵称为%@",userName);
 
     //OC语言转化为C语言
     NSString *ocStr = @"猫爷爷的酱醋茶";
     const char * cStr= ocStr.UTF8String;
 
 
6.读写字符串
 
    a）将字符串内存写入到磁盘上的某一个文件内  - 例：WriteToFile();
 
    - (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
 
    参数1：将字符串内容写入到那个文件的文件路径
    参数2：YES，先将内容写到一个临时文件，如果成功再将这个文件搬到指定的目录。特点：安全，效率较低。
          NO，直接将内容写入到指定的文件中。特点：不安全，效率高。
 
    参数3：指定写入的时候使用的编码。 一般情况下使用：NSUTF8StringEncoding，使用UTF-8编码。
    参数4：二级指针，要传递一个NSError类型的指针地址。
    如果写入成功，这个指针的值为nil
    如果写入失败，这个指针就会指向一个对象，这个对象描述了错误信息，所以我们可以输出错误信息查看
    对象的localizedDescription方法可以得到发送错误的简要信息。
 
    返回值BOOL类型，代表是否写入成功。
 
    b）将磁盘上的文件中读取文件中的内容 例：WriteToFile();
 
    + (nullable instancetype)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;
 
 
7. 使用URL读取字符串数据
 
    a）优势：既可以读取本地文件 也可以读取网页文件、ftp服务器文件
    b）不同类型的URL地址的写法：
        本地磁盘文件：file://
        网页地址：http://
        ftp文件的地址：ftp://
    c）将不同类型的地址封装在NSURL对象之中
 
 
8. 查找字符串中是否存在指定的字符串 - 例：RangOfString();
 
    - (NSRange)rangeOfString:(NSString *)searchString;
 
    [str rangeOfString:@""];  //从左往右搜索
    [str rangeOfString:@"" options:NSBackwardSeatch]; //从后往前搜索
 
    返回值NSRange  - 通常用来表示一段范围
    typedef struct _NSRange
    {
        NSUInteger location;  //代表子串在字符串中出现的下标，如果没有找到，会是NSNotFound的最大值
        NSUInteger length;     //代表子串在字符串中匹配的长度，如果没有找到，值为0
    } NSRange;
 
    初始化的方式:
    a） NSRange range;
        range.location = 3;
        range.length = 4;
 
    b） NSRange range = {3,4};
 
    c）NSRange range = {.location = 3,.length = 4};
 
    Foundation框架中定义了一个函数，可以快速创建一个NSRange结构体
    - NSRange range = NSMakeRange(3, 4) ;
 
    Foundation框架中定义了一个函数，可以将一个NSRange结构体变量转换为NSString
    - NSStringFromRange(range);
 
 
9. 截取字符串 -  例：RangOfString();
 
    - (NSString *)substringFromIndex:(NSUInteger)from; //从指定的下标一直截取到最后
    - (NSString *)substringToIndex:(NSUInteger)to; //从下标为0开始截取指定的个数
    - (NSString *)substringWithRange:(NSRange)range; //截取指定的范围
 
 
10. 字符串的替换、删除（替换为空字符串@“”） - RangOfString();
 
    - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement
    将字符串中的第一个参数替换为第二个参数。
    注意：a）原来的指针指向的字符串内容是不会变的。
         b）全部替换。
 
 
11. 字符串转换为其他类型
    直接使用.interValue ...
    转换注意：从头开始转换，能转换多少是多少，遇到不能转换的时候就停止转换。
 
12. 修改字符串前后的空格 - TrimmingTheString();
 
 
 
 
 */
#import <Foundation/Foundation.h>
#import "StudentPackage.h"
#define LogBOOL(var) NSLog(@"%@",var==YES?@"YES":@"NO")

//C语言转换成OC语言
void Conversion(void);

//字符串拼接
void Splice(void);

//对象方法
void ObjetctMethod(void);

//封装对象
void PackageStudent(void);

//字符串地址
void NSStringAddress(void);

//将字符串写入磁盘某个文件内
void WriteToFile(void);

//判断字符串是否以指定的字符串开头或结尾
void StringHasPrefixOrHasSuffix(void);

//查找字符串是否存在指定的字符串
void RangOfString(void);

//字符串转换为其他数据类型
void ConversationOfString(void);

//更改字符串
void TrimmingTheString(void);


int main(int argc, const char * argv[])
{
    
    TrimmingTheString();
    
    return 0;
}

//修剪字符串
void TrimmingTheString(void)
{
    //去掉字符串首尾的空格
    NSString *str = @"      You should be study hard.     ";
    str = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    NSLog(@"%@",str);
    
    //字符串中的字母转化为大写
    str = [str uppercaseString];
    NSLog(@"%@",str);
    
    //字符串中的字母转化为小写
    str = [str lowercaseString];
    NSLog(@"%@",str);
    
    //去掉字符串中前后的小写字母
    NSString *str0 = @"bilibiliSayHello！bilibii";
    str0 = [str0 stringByTrimmingCharactersInSet:[NSCharacterSet lowercaseLetterCharacterSet]];
    NSLog(@"%@",str0);
    
    //去掉字符串前后的大写字母
    NSString *str1 = @"ABABit's sounds goodABABC";
    str1 = [str1 stringByTrimmingCharactersInSet:[NSCharacterSet uppercaseLetterCharacterSet]];
    NSLog(@"%@",str1);
    
    //去掉字符串中前后指定的字符串
    NSString *str2 = @"oOo猫爷爷的酱醋茶oOo";
    str2 = [str2 stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"oOo"]];
    NSLog(@"%@",str2);
    
}

//字符串转换为其他数据类型
void ConversationOfString(void)
{
    
    NSString *str = @"123aa";
    int num = str.intValue;
    float num1 = str.floatValue;
    double num2 = str.doubleValue;
    
    NSLog(@"num = %d,num1 = %.2f,num2 = %.2lf",num,num1,num2);
}

//查找字符串是否存在指定的字符串
void RangOfString(void)
{
    
    NSString *str = @"You should be study hard.";
    NSRange range = [str rangeOfString:@"study"];
    
    if(range.length == 0)
    {
        NSLog(@"没有包含指定的字符串");
    }else{
        NSLog(@"找到了！在下标为%lu开始，长度为%lu。",range.location,range.length);
    }
    
    //字符串的截取
    NSString *subStr0 = [str substringToIndex:13];
    NSString *subStr1 = [str substringFromIndex:14];
    NSString *subStr2 = [str substringWithRange:NSMakeRange(14, 5)];
    
    NSLog(@"subStr0 = %@",subStr0);
    NSLog(@"subStr1 = %@",subStr1);
    NSLog(@"subStr2 = %@",subStr2);
    
    //字符串的替换
    [str stringByReplacingOccurrencesOfString:@"You" withString:@"We"];
    
    //替换后原来的指针指向的地址不变，所以字符串的内容也不变
    NSLog(@"%@",str);
    
    //需要重新复制才行
    str = [str stringByReplacingOccurrencesOfString:@"You" withString:@"We"];
    NSLog(@"%@",str);
    
    
}



//判断字符串是否以指定的字符串开头或结尾
void StringHasPrefixOrHasSuffix(void)
{
    
    NSString *https = @"https://www.baidu.com";
    NSString *paths = @"file:///User/Admin/Desktop/男孩.mp3";
    
    BOOL resOne = [https hasPrefix:@"https://"]; LogBOOL(resOne);
    BOOL resTwo = [paths hasSuffix:@".mp3"]; LogBOOL(resTwo);
    
}


void WriteToFile(void)
{
    
    //将字符串写入磁盘某个文件内
    NSString *str = @"猫爷爷的酱醋茶 要再抓紧点时间";
    
    NSError *error;
    BOOL res = [str writeToFile:@"/Users/Admin/Desktop/test.txt" atomically:NO encoding:NSUTF8StringEncoding error:&error];
    
    if (res == YES)
    {
        NSLog(@"wirteToFile文件写入成功");
    }else{
        NSLog(@"wirteToFile文件写入失败,%@",error);
    }
    
    //使用URL读取字符串数据
//    NSURL *urlOne = [NSURL URLWithString:@"http://www.baidu.com"];
    //如果文件路径有空格容易出错
    NSURL *urlTwo = [NSURL URLWithString:@"file:///Users/Admin/Desktop/test.txt"];
    NSString *strOne = [NSString stringWithContentsOfURL:urlTwo encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"通过URL读取：%@",strOne);
    
    //通过URL写入字符串
    NSString *wirteTo = @"成为IOS初级工程师";
    BOOL resUrl = [wirteTo writeToURL:urlTwo atomically:NO encoding:NSUTF8StringEncoding error:nil];

    if (resUrl == YES)
    {
        NSLog(@"通过URL写入成功");
    }else{
        NSLog(@"通过URL写入失败");
    }

    
    //读取磁盘上的文件
    NSError *error0;
    
    NSString *str0 = [NSString stringWithContentsOfFile:@"/Users/Admin/Desktop/Study OC/NSString/test.txt" encoding:NSUTF8StringEncoding error:&error0];
    
    if (error0 != nil)
    {
        NSLog(@"读取文件失败");
    }else{
        NSLog(@"通过stringWithContent读取文件成功，%@",str0);
    }
    
}

//字符串地址
void NSStringAddress(void)
{
    NSString *str = @"猫爷爷的酱醋茶"; //定义在常量区
    NSString *str0 = [NSString stringWithFormat:@"猫爷爷的酱醋茶"];//定义在堆区
    NSLog(@"\nstr 的地址为%p\nstr0的地址为%p",str,str0);//两者的地址差距很大
    str = @"IOS开发者";
    NSLog(@"str的地址为%p",str);//str的值与初始化的值不同
    
    NSString *str2 = @"猫爷爷的酱醋茶";
    NSLog(@"str2的地址为%p",str2); //它的地址与str 指向 @”猫爷爷的酱醋茶“ 的地址一样
    
}

//封装对象
void PackageStudent(void)
{
    Student *stuNo1 = [Student new];
    [stuNo1 setName:@"包子"];
    [stuNo1 setAge:18];
    [stuNo1 setChineseScore:95.5];
    [stuNo1 setMathScore:85];
    [stuNo1 setEnglishScore:92];
    [stuNo1 SayHi];
}

//对象方法
void ObjetctMethod(void)
{
    NSString *name = @"猫爷爷的酱醋茶";
    //字符串长度
    NSUInteger length = [name length];
    NSLog(@"该字符串的长度为%lu",length);
    
    //取指定的字符串
    NSString *userName = @"jack";
    unichar str = [userName characterAtIndex:1];
    NSLog(@"str = %c",str);
    
    //提取中文输出需要用%C  中文在OC中占据两个字节
    unichar str0 = [name characterAtIndex:2];
    NSLog(@"昵称中的第三个值为%C",str0);
    
    NSString *name0 = [NSString stringWithFormat:@"猫爷爷的酱醋茶"];
    
    //判断两个字符串的内容时候相等，不要用==去判断，因为容易出错，如下：
    if (name == name0)
    {
        NSLog(@"YES,name和name0是相等的");
    }else{
        NSLog(@"出错了,name和name0应该要是相等的");
        
    }
    
    //比较字符串的内容时候相等
    if([name isEqualToString:name0])
    {
        NSLog(@"对的,name和name0是相等的");
    }
    
    //比较两个字符的大小
    if([name compare:name0] == 0)
    {
        NSLog(@"通过ASCII又判断了一下，没错,name和name0是相等的");
    }
    
    //忽略大小写的比较
    NSString *lowerCase = @"jack";
    NSString *capital = @"JACK";
    
    
    if ([lowerCase compare:capital options:NSCaseInsensitiveSearch] == 0)
    {
        NSLog(@"忽略大小写，%@和%@是相等的",lowerCase,capital);
    }
    
    //比较字符串中的数字大小
    NSString *pngStrOne = @"pic100071.png";
    NSString *pngStrTwo = @"pic100071.png";
    
    int res = [pngStrOne compare:pngStrTwo options:NSNumericSearch];
    switch (res) {
        case -1:
            NSLog(@"pngStrOne < pngStrTwo");
            break;
        case 0:
            NSLog(@"pngStrOne = pngStoTwo");
            break;
        default:
            NSLog(@"pngStrOne > pngStoTwo");
            break;
    }
}

//字符串拼接
void Splice(void)
{
    
    int age = 22;
    NSString *name = @"猫爷爷的酱醋茶";
    NSString *str = [NSString stringWithFormat:@"钻石会员用户的昵称是%@，年龄为%d。",name,age];
    NSLog(@"str = %@",str);
    
}


//C语言与OC语言的互相转换
void Conversion(void)
{
    //C语言转OC语言
    NSLog(@"请为该账号取一个昵称");
    char name[10];
    rewind(stdin);
    scanf("%s",name);
    
    NSString *userName = [NSString stringWithUTF8String:name];
    NSLog(@"用户昵称为%@",userName);
    
    //OC语言转化为C语言
    NSString *ocStr = @"猫爷爷的酱醋茶";
    const char * cStr= ocStr.UTF8String;
    NSLog(@"%s",cStr);
}
